// Kokomi.js - Three.js 组件框架
import * as kokomi from "kokomi.js";
// Three.js - 3D 渲染引擎
import * as THREE from "three";
// three-stdlib - Three.js 标准库
import * as STDLIB from "three-stdlib";

import type Experience from "../Experience";

// 反射地板的自定义着色器
import reflecFloorVertexShader from "../Shaders/ReflecFloor/vert.glsl";
import reflecFloorFragmentShader from "../Shaders/ReflecFloor/frag.glsl";

// 自定义的网格反射材质
import { MeshReflectorMaterial } from "../Utils/meshReflectorMaterial";

/**
 * 起始房间组件
 * 包含房间模型、灯光和反射地板
 * 地板使用自定义着色器实现实时反射效果
 */
export default class StartRoom extends kokomi.Component {
  declare base: Experience; // Experience 实例引用
  model: STDLIB.GLTF; // 房间 GLTF 模型
  uj: kokomi.UniformInjector; // Uniform 注入器
  lightMat: THREE.MeshStandardMaterial; // 灯光材质
  customFloorMat: kokomi.CustomShaderMaterial; // 地板自定义材质
  lightBoard: THREE.Mesh; // 灯光板网格
  reflecFloor: THREE.Mesh; // 反射地板网格
  
  constructor(base: Experience) {
    super(base);

    // 加载房间模型
    const model = this.base.am.items["sm_startroom"] as STDLIB.GLTF;
    this.model = model;

    // 将模型场景树展平为数组
    const modelParts = kokomi.flatModel(model.scene);
    // kokomi.printModel(modelParts); // 调试用：打印模型结构

    // ==================== 设置灯光材质 ====================
    const light001 = modelParts[1] as THREE.Mesh;
    this.lightBoard = light001; // 保存灯光板引用
    const lightMat = light001.material as THREE.MeshStandardMaterial;
    this.lightMat = lightMat;
    lightMat.emissive = new THREE.Color("white"); // 自发光颜色：白色
    lightMat.emissiveIntensity = 1; // 自发光强度
    lightMat.toneMapped = false; // 禁用色调映射（保持明亮）
    lightMat.transparent = true; // 启用透明
    this.lightMat.alphaTest = 0.1; // Alpha 测试阈值

    // ==================== 设置地板材质 ====================
    const ReflecFloor = modelParts[2] as THREE.Mesh;
    this.reflecFloor = ReflecFloor; // 保存地板引用
    const floorMat = ReflecFloor.material as THREE.MeshPhysicalMaterial;
    // 应用各种贴图
    floorMat.aoMap = this.base.am.items["ut_startroom_ao"]; // AO 贴图
    floorMat.lightMap = this.base.am.items["ut_startroom_light"]; // 光照贴图
    floorMat.normalMap = this.base.am.items["ut_floor_normal"]; // 法线贴图
    floorMat.roughnessMap = this.base.am.items["ut_floor_roughness"]; // 粗糙度贴图
    floorMat.envMapIntensity = 0; // 环境映射强度设为 0

    // const reflectPlane = new THREE.Mesh(
    //   new THREE.PlaneGeometry(100, 100),
    //   new THREE.MeshBasicMaterial()
    // );
    // reflectPlane.rotation.x = -Math.PI / 2;
    // this.container.add(reflectPlane);
    // const reflectMat = new kokomi.MeshReflectorMaterial(
    //   this.base,
    //   reflectPlane,
    //   {
    //     resolution: 1024,
    //     blur: [1000, 1000],
    //     mixBlur: 4,
    //     mixStrength: 1,
    //     mirror: 1,
    //   }
    // );
    // // @ts-ignore
    // reflectPlane.material = reflectMat.material;
    // ReflecFloor.visible = false;

    // ==================== 创建自定义地板材质 ====================
    const uj = new kokomi.UniformInjector(this.base);
    this.uj = uj;

    // 使用 CustomShaderMaterial 扩展现有材质
    const customFloorMat = new kokomi.CustomShaderMaterial({
      baseMaterial: floorMat, // 基础材质（保留原有的物理属性）
      vertexShader: reflecFloorVertexShader, // 自定义顶点着色器
      fragmentShader: reflecFloorFragmentShader, // 自定义片元着色器
      uniforms: {
        ...uj.shadertoyUniforms, // Shadertoy 风格的 uniform
        uColor: {
          value: new THREE.Color("#ffffff"), // 地板颜色（白色）
        },
        uSpeed: {
          value: this.base.params.speed, // 当前速度
        },
        uReflectMatrix: {
          value: new THREE.Matrix4(), // 反射矩阵
        },
        uReflectTexture: {
          value: null, // 反射纹理（后续赋值）
        },
        uReflectIntensity: {
          value: 25, // 反射强度
        },
        uMipmapTextureSize: {
          value: new THREE.Vector2(window.innerWidth, window.innerHeight), // Mipmap 纹理尺寸
        },
      },
    });
    this.customFloorMat = customFloorMat;
    // 应用自定义材质到地板
    ReflecFloor.material = customFloorMat;

    // 监听窗口大小变化，更新 Mipmap 纹理尺寸
    this.base.resizer.on("resize", () => {
      this.customFloorMat.uniforms.uMipmapTextureSize.value = new THREE.Vector2(
        window.innerWidth,
        window.innerHeight
      );
    });

    // const reflectMat = new kokomi.MeshReflectorMaterial(
    //   this.base,
    //   ReflecFloor,
    //   {
    //     resolution: 1024,
    //     blur: [1000, 1000],
    //     mixBlur: 4,
    //     mixStrength: 1,
    //     mirror: 1,
    //     ignoreObjects: [ReflecFloor],
    //   }
    // );
    // customFloorMat.uniforms.uReflectMatrix.value =
    //   reflectMat.material._textureMatrix.value;
    // customFloorMat.uniforms.uReflectTexture.value =
    //   reflectMat.material._tDiffuse.value;

    // ==================== 创建实时反射材质 ====================
    const reflectMat = new MeshReflectorMaterial(this.base, ReflecFloor, {
      resolution: 1024, // 反射纹理分辨率
      ignoreObjects: [light001, ReflecFloor], // 忽略的对象（不参与反射）
    });
    // 将反射矩阵和纹理传递给自定义材质
    customFloorMat.uniforms.uReflectMatrix.value = reflectMat._reflectMatrix;
    // customFloorMat.uniforms.uReflectTexture.value =
    //   reflectMat._renderTexture.rt.texture; // 可选：使用普通纹理
    customFloorMat.uniforms.uReflectTexture.value =
      reflectMat.mipmapFBO.rt.texture; // 使用 Mipmap 纹理（更高效）
  }
  /**
   * 将房间模型添加到场景
   */
  addExisting() {
    this.container.add(this.model.scene);
  }
  
  /**
   * 每帧更新
   * 更新 Shadertoy uniforms 和速度参数
   */
  update(): void {
    // 注入 Shadertoy 风格的 uniform（时间、分辨率等）
    this.uj.injectShadertoyUniforms(this.customFloorMat.uniforms);

    // 更新当前速度值
    this.customFloorMat.uniforms.uSpeed.value = this.base.params.speed;
  }
}
